package com.wkbb.sports.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BeanBind {
	
	private Class<?> beanClass;
	private Map<String, Method> propertyGets = new HashMap<>();
	private Map<String, Method> propertySets = new HashMap<>();

	public BeanBind(Class<?> sourceBeanClass, Class<?> targetBeanClass)throws Exception {
		this.beanClass = targetBeanClass;
		buildGetProperty(sourceBeanClass);
		buildSetProperty(targetBeanClass);
	}

	private void buildSetProperty(Class<?> targetBeanClass)throws Exception {
		for(Field field : beanClass.getDeclaredFields()) {
			int mod = field.getModifiers();
			if(Modifier.isStatic(mod)||Modifier.isFinal(mod)) {
				continue;
			}
			String propName = field.getName();
			Class<?> paramClass = field.getType();
			String methodName = "set" + propName.substring(0, 1).toUpperCase() + propName.substring(1);
    		Method method = targetBeanClass.getMethod(methodName, paramClass);
    		propertySets.put(propName, method);
		};
	}

	private void buildGetProperty(Class<?> beanClass) throws Exception {
		for(Field field : beanClass.getDeclaredFields()) {
			int mod = field.getModifiers();
			if(Modifier.isStatic(mod)||Modifier.isFinal(mod)) {
				continue;
			}
			String propName = field.getName();
			String methodName = "get" + propName.substring(0, 1).toUpperCase() + propName.substring(1);
    		Method method = beanClass.getMethod(methodName);
    		propertyGets.put(propName, method);
		};
	}
	
	public Object bindBean(Object sourceBean)throws Exception {
		if(sourceBean == null) {
			return null;
		}
		Object targetBean = beanClass.newInstance();
		for(String key : propertySets.keySet()) {
			Method getMethod = propertyGets.get(key);
			if(getMethod == null) {
				continue;
			}
			Object value = getMethod.invoke(sourceBean);
			Method setMethod = propertySets.get(key);
			try{
				setMethod.invoke(targetBean, value);
			}catch(Throwable e) {
				System.out.println(setMethod.getName() + "(" + value + ")");
				e.printStackTrace();
			}
		}
		return targetBean;
	}
	
	public List<?> bindBeans(List<?> sourceBeans)throws Exception {
		List<Object> list = new ArrayList<>();
		for(Object sourceBean : sourceBeans) {
			Object target = bindBean(sourceBean);
			list.add(target);
		}
		return list;
	}
}
